﻿using PagedList;
using System.Text;
using System.Web;
using System.Collections.Specialized;

namespace Web.Base.Components
{
    /// <summary>
    /// 分页类 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Pager<T>
    {
        /// <summary>
        /// id
        /// </summary>
        private readonly string id;

        private readonly string url;

        private IPagedList<T> PaginatedList { get; set; }

        public Pager(IPagedList<T> paginatedList)
        {
            id = "pager";
            url = HttpContext.Current.Request.QueryString.ToQueryStringWithPage();
            PaginatedList = paginatedList;
        }

        #region GetLink
        private string GetTextLink(int currentPageIndex, int start, int end, bool hasEllipsis)
        {
            var html = string.Empty;
            if (start < end)
            {
                if (hasEllipsis)
                {
                    html += "<span>...</span>";
                }
                for (var i = start; i <= end; i++)
                {
                    html += GetTextLink(currentPageIndex, i, i.ToString());
                }
            }
            return html;
        }

        private string GetTextLink(int currentPageIndex, int pageIndex, string text)
        {
            var pagingUrl = GetPagingUrl(pageIndex);
            return pageIndex == currentPageIndex ? string.Format("<a class=\"cur\">{0}</a>", text) : string.Format("<a href=\"{0}\">{1}</a>", pagingUrl, text);
        }

        #endregion

        #region GetPagingUrl
        private string GetPagingUrl(int newIndex)
        {
            return url.Replace("pageIndex", newIndex.ToString());
        }

        #endregion
        public override string ToString()
        {
            var pageIndex = PaginatedList.PageNumber > 0 ? PaginatedList.PageSize : 1;
            var totalRecord = PaginatedList.TotalItemCount > 0 ? PaginatedList.TotalItemCount : 0;
            var pageSize = PaginatedList.PageSize > 1 ? PaginatedList.PageSize : 1;
            if (totalRecord > pageSize)
            {
                const int linkCount = 9;
                var endIndexFront = 0;
                var startIndexMiddle = 0; //中间显示的起始链接页(例如5:1 2 ... 5 6 7 8 9 ... 11 12)
                var endIndexMiddle = 0; //中间显示的结束链接页(例如9:1 2 ... 5 6 7 8 9 ... 11 12)
                var startIndexBack = 0; //右边显示的起始链接页(例如11:1 2 ... 5 6 7 8 9 ... 11 12)
                const int maxLinkCountSide = 5;
                const int linkCountMiddle = 5;
                const int minLinkCountSite = 2;

                var pageItemCount = pageIndex * pageSize - totalRecord;
                pageItemCount = pageItemCount > 0 ? pageSize - pageItemCount : pageSize;
                var pageItemBegin = (pageIndex - 1) * pageSize + 1;
                var pageItemEnd = pageItemBegin + pageItemCount - 1;
                var pageCount = (totalRecord / pageSize) + (totalRecord % pageSize == 0 ? 0 : 1);
                pageIndex = pageIndex <= pageCount ? pageIndex : pageCount;

                //  如果当前页的总数<=linkCount的值,则全部显示(1 2 3)
                if (pageCount <= linkCount)
                {
                    endIndexFront = pageCount;
                    startIndexMiddle = 0;
                    endIndexMiddle = 0;
                    startIndexBack = pageCount;
                }
                else
                {
                    //  1 2 3 4 5 ...11 12(如果当前页<左边的链接总数)
                    if (pageIndex < maxLinkCountSide)
                    {
                        endIndexFront = maxLinkCountSide;
                        startIndexMiddle = 0;
                        endIndexMiddle = 0;
                        startIndexBack = pageCount + 1 - minLinkCountSite;
                    }
                    //  1 2 ... 5 6 7 8 9 ... 11 12
                    else if (pageIndex >= maxLinkCountSide && pageIndex <= (pageCount - maxLinkCountSide + 1))
                    {
                        const int halfmiddleLinkCount = (linkCountMiddle + 1) / 2;
                        endIndexFront = minLinkCountSite;
                        startIndexMiddle = pageIndex - halfmiddleLinkCount + 1;
                        endIndexMiddle = startIndexMiddle - 1 + linkCountMiddle;
                        startIndexBack = pageCount + 1 - minLinkCountSite;
                    }
                    //  1 2 ... 8 9 10 11 12
                    else if (pageIndex > (pageCount - maxLinkCountSide + 1))
                    {
                        endIndexFront = minLinkCountSite;
                        startIndexMiddle = 0;
                        endIndexMiddle = 0;
                        startIndexBack = pageCount + 1 - maxLinkCountSide;
                    }
                }

                var html = new StringBuilder();
                html.AppendFormat("<div id=\"{0}\" class=\"pager\"><ul>", id);
                html.AppendFormat("<li class=\"record\"><span>当前{0}-{1}条/总共{2}条</span></li>", pageItemBegin, pageItemEnd,
                                  totalRecord);

                if (PaginatedList.HasPreviousPage)
                {
                    html.AppendFormat("<li class=\"first\"><a href=\"{0}\">首 页</a></li>", GetPagingUrl(1));
                    html.AppendFormat("<li class=\"prev\"><a href=\"{0}\">上一页</a></li>", GetPagingUrl(pageIndex - 1));
                }
                else
                {
                    html.Append("<li class=\"first off\"><span>首 页</span></li>");
                    html.Append("<li class=\"prev off\"><span>上一页</span></li>");
                }

                html.Append("<li class=\"page\">");

                html.Append(GetTextLink(pageIndex, 1, endIndexFront, false));
                html.Append(GetTextLink(pageIndex, startIndexMiddle, endIndexMiddle, true));
                html.Append(GetTextLink(pageIndex, startIndexBack, pageCount, true));

                html.Append("</li>");

                if (PaginatedList.HasNextPage)
                {
                    html.AppendFormat("<li class=\"next\"><a href=\"{0}\">下一页</a></li>", GetPagingUrl(pageIndex + 1));
                    html.AppendFormat("<li class=\"last\" ><a href=\"{0}\">尾 页</a></li>", GetPagingUrl(pageCount));
                }
                else
                {
                    html.Append("<li class=\"next off\"><span>下一页</span></li>");
                    html.Append("<li class=\"last off\"><span>尾 页</span></li>");
                }
                html.AppendFormat("<li class=\"record\"><span>第{0}页/共{1}页</span></li>", pageIndex, pageCount);

                html.Append("</ul></div>");
                return html.ToString();
            }
            return string.Empty;
        }
    }
    internal static class Extension
    {
        public static string ToQueryStringWithPage(this NameValueCollection queryString)
        {
            var qs = new StringBuilder();
            qs.Append("?");

            if (queryString.Count > 0)
            {
                for (var i = 0; i < queryString.Count; i++)
                {
                    if (string.IsNullOrEmpty(queryString[i].Trim()) || queryString.Keys[i].ToLower().Trim() == "page")
                        continue;

                    qs.AppendFormat("{0}={1}&", queryString.Keys[i].Trim(), queryString[i].Trim());
                }
            }
            return qs.Append("page=pageIndex").ToString();
        }
    }
}
